package com.liu.qqRobot.poke.handler;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.liu.common.content.RedisKeyInterface;
import com.liu.common.utils.HtmlToImageUtils;
import com.liu.common.utils.QQClientUtils;
import com.liu.mybatisPlus.poke.entity.base.PokeDuel;
import com.liu.mybatisPlus.poke.entity.base.PokeDuelDetail;
import com.liu.mybatisPlus.poke.service.PokeDuelDetailService;
import com.liu.mybatisPlus.poke.service.PokeDuelService;
import com.liu.mybatisPlus.poke.service.PokeGroupUserPokeService;
import com.liu.mybatisPlus.q.service.QGroupUserOperationQuantityService;
import com.liu.qqRobot.event.entity.dto.EventReportingDTO;
import com.liu.qqRobot.poke.entity.dto.PokeDTO;
import com.liu.qqRobot.q.enums.OperationTypeEnum;
import freemarker.template.TemplateException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
public class UseSkillHandler {

    @Resource
    private PokeDuelService pokeDuelService;

    @Resource
    private PokeGroupUserPokeService pokeGroupUserPokeService;

    @Resource
    private PokeDuelDetailService pokeDuelDetailService;

    @Resource
    private QGroupUserOperationQuantityService qGroupUserOperationQuantityService;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 处理事件
     * @param data 信息内容
     * @param groupId 群号
     * @param userId 发送人QQ号
     */
    public void handler(EventReportingDTO.Message.Data data, Long groupId, Long userId, Boolean isGroup) {
        String text = data.getText();
        String pokeSkillName = text.replace("使用 ", "");
        QueryWrapper<PokeDuel> pokeDuelQueryWrapper = new QueryWrapper<>();
        pokeDuelQueryWrapper.eq("group_id", groupId);
        pokeDuelQueryWrapper.eq("is_end", 0);
        pokeDuelQueryWrapper.eq("next_use_user_id", userId);
        PokeDuel userPokeDuel = pokeDuelService.getOne(pokeDuelQueryWrapper);
        if (userPokeDuel == null || !Objects.equals(userId, userPokeDuel.getNextUseUserId())) {
            return;
        }
        QueryWrapper<PokeDuelDetail> pokeDuelDetailQueryWrapper = new QueryWrapper<>();
        pokeDuelDetailQueryWrapper.eq("duel_id", userPokeDuel.getId());
        List<PokeDuelDetail> pokeDuelDetailList = pokeDuelDetailService.list(pokeDuelDetailQueryWrapper);
        int maxSort = 2;
        if (CollUtil.isNotEmpty(pokeDuelDetailList)) {
            maxSort = pokeDuelDetailList.stream().map(PokeDuelDetail::getSort).max(Comparator.naturalOrder()).get();
        }
        Integer pokeId = null;
        Integer otherPokeId = null;
        Long otherUserId = null;
        if (Objects.equals(userPokeDuel.getUser1Id(), userPokeDuel.getNextUseUserId())) {
            pokeId = userPokeDuel.getUser1PokeId();
            otherPokeId = userPokeDuel.getUser2PokeId();
            otherUserId = userPokeDuel.getUser2Id();
        } else if (Objects.equals(userPokeDuel.getUser2Id(), userPokeDuel.getNextUseUserId())){
            pokeId = userPokeDuel.getUser2PokeId();
            otherPokeId = userPokeDuel.getUser1PokeId();
            otherUserId = userPokeDuel.getUser1Id();
        } else {
            return;
        }
        PokeDTO userPoke = pokeGroupUserPokeService.getPokeByUserIdAndPokeId(groupId, userId, pokeId);
        PokeDTO otherUserPoke = pokeGroupUserPokeService.getPokeByUserIdAndPokeId(groupId, otherUserId, otherPokeId);
        PokeDuelDetail pokeDuelDetail = new PokeDuelDetail();
        pokeDuelDetail.setSort(maxSort + 1);
        pokeDuelDetail.setUserId(userId);
        pokeDuelDetail.setDuelId(userPokeDuel.getId());
        StringBuilder content = new StringBuilder();
        content.append("【").append(userPoke.getPokeName()).append("】使用：");
        Integer otherUserPokeHP = Integer.valueOf(redisTemplate.opsForValue().get(RedisKeyInterface.POKE_HP_REDIS_KEY + userPokeDuel.getId() + otherUserId));
        Integer userPokeHP = Integer.valueOf(redisTemplate.opsForValue().get(RedisKeyInterface.POKE_HP_REDIS_KEY + userPokeDuel.getId() + userId));
        int skillAggressivity = 0;
        if (pokeSkillName.equals("普通攻击")) {
            skillAggressivity = userPoke.getAggressivity();
            content.append("【普通攻击】，使【").append(otherUserPoke.getPokeName()).append("】HP减少").append(userPoke.getAggressivity());
            redisTemplate.opsForValue().set(RedisKeyInterface.POKE_HP_REDIS_KEY + userPokeDuel.getId() + otherUserId, String.valueOf(otherUserPokeHP - userPoke.getAggressivity()));
            if (otherUserPokeHP - userPoke.getAggressivity() <= 0) {
                content.append("，【").append(otherUserPoke.getPokeName()).append("】HP归零，【").append(userPoke.getPokeName()).append("】获得胜利");
                userPokeDuel.setStatus(2);
                userPokeDuel.setWinnerUserId(userId);
                redisTemplate.delete(RedisKeyInterface.POKE_HP_REDIS_KEY + userPokeDuel.getId() + otherUserId);
                redisTemplate.delete(RedisKeyInterface.POKE_HP_REDIS_KEY + userPokeDuel.getId() + userId);
            }
        } else {

        }
        pokeDuelDetail.setContent(content.toString());
        pokeDuelDetailService.save(pokeDuelDetail);
        pokeDuelDetailList.add(pokeDuelDetail);
        pokeDuelDetailList = pokeDuelDetailList.stream().sorted(Comparator.comparing(PokeDuelDetail::getSort)).collect(Collectors.toList());

        Map<String, Object> templateParam = new HashMap<>();
        templateParam.put("pokeName1", userPoke.getPokeName());
        templateParam.put("pokeName2", otherUserPoke.getPokeName());
        templateParam.put("pokeHP1", userPokeHP);
        templateParam.put("pokeHP2", otherUserPokeHP - skillAggressivity);
        templateParam.put("aggressivity1", userPoke.getAggressivity());
        templateParam.put("aggressivity2", otherUserPoke.getAggressivity());
        templateParam.put("userName1", (userPoke.getGroupUserName() == null ? userPoke.getUserName():userPoke.getGroupUserName()));
        templateParam.put("userName2", (otherUserPoke.getGroupUserName() == null ? otherUserPoke.getUserName():otherUserPoke.getGroupUserName()));
        templateParam.put("pokeImageUrl1", userPoke.getPokeImageUrl());
        templateParam.put("pokeImageUrl2", otherUserPoke.getPokeImageUrl());
        templateParam.put("contentList", pokeDuelDetailList.stream().map(PokeDuelDetail::getContent).collect(Collectors.toList()));
        try {
            HtmlToImageUtils.htmlToImage("pokeDuelTemplate.html", templateParam, "src/main/resources/picture/pokeDuel.png", 2000);
            File file = new File("src/main/resources/picture/pokeDuel.png");
            String encode = Base64.encode(file);
            String msg = "[CQ:at,qq=" + userId + "]\n[CQ:image,file=base64://" + encode+ ",type=show,subType=0]";
            QQClientUtils.sendMsg(msg, userId, groupId, isGroup);
            qGroupUserOperationQuantityService.statisticsOperationQuantityByType(groupId, userId, OperationTypeEnum.POKE_DUEL);
        } catch (IOException | ParserConfigurationException | SAXException | TemplateException e) {
            log.error("获取宝可梦对决展示模板失败:{}", e.getMessage(), e);
//            QQClientUtils.sendGroupMsg("[CQ:at,qq=" + userId + "]\n获取捕捉宝可梦展示模板失败，请联系制作人", userId, groupId, isGroup);
        }
        userPokeDuel.setNextUseUserId(otherUserId);
        pokeDuelService.updateById(userPokeDuel);
        if (userPokeDuel.getStatus() != 2) {
            QQClientUtils.sendMsg("[CQ:at,qq=" + otherUserId + "]\n请开始行动，发送指令：使用 XXX", otherUserId, groupId, isGroup);
        }
    }
}
